// /////////////////////////////////////////////////////////////////////////////
//
// Name:            DataStack.h
// Author:          Michael Bartsch (ZCCdark203)
//
// Desc :           Declaration of the DataStack class.
//
// License:         Copyright (C) 2009 Michael Bartsch and Contributors
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the zlib/libpng License.
//                  See main.cpp for conditions of distribution and use.
//
// /////////////////////////////////////////////////////////////////////////////

#ifndef __DATASTACK_H__
#define __DATASTACK_H__

// Include files
#include "../dependencies.h"
#include "ReferenceCounted.h"
#include "DataStore.h"

// Forward declarations.
class DataStore;


// DataStack class
//! DataStacks provide an interface for storing (and removing)
//! variables that can be accessed from anywhere within the
//! framework. Furthermore it's also possible to save these
//! variables into files.
class DataStack : public ReferenceCounted
{
public:

    // Initialisation and deinitialisation
    //! Constructor
    //! @param name          Name of the DataStack.
    DataStack(const std::string &name);
    //! Deconstructor
    ~DataStack();

    //! Initialises the DataStack.
    void init();
    //! Clears the DataStack.
    void clear();

    // Methods
    //! Gets the ID of the DataStack.
    u32 getID() const;
    //! Gets the name of the DataStack.
    const std::string& getName() const;

    //! Gets the number of variables on the DataStack.
    u32 getSize() const;

    //! Sets the variable with the given name.
    //! @param name          Name of the variable to set.
    //! @param value         Value of the variable.
    //! @note This function is not directly available in AngelScript. You can use the
    //!       set_<valuetype> functions, though.
    template<typename T>
    bool setVar(const std::string &name, const T &value)
    {
        // Convert the variable.
        std::stringstream ss;
        ss << value;

        // In case the variable has been converted we'll store it.
        if(ss.good())
        {
           mVars[name] = ss.str();
           return true;
        }

        // The variable hasn't been converted correctly.
        else return false;
    };

    //! Gets the variable with the given name.
    //! @param name          Name of the variable.
    //! @return The value of the given variable.
    //! @note This function is not directly available in AngelScript. You can use the
    //!       get_<valuetype> functions, though.
    template<typename T>
    T getVar(const std::string &name)
    {
        // Try to find the given variable.
        std::map<std::string, std::string>::iterator it;
        it = mVars.find(name);

        // Did we find the variable?
        if(it != mVars.end())
        {
           std::stringstream ss(it->second);
           T t;

           ss >> t;
           return t;
        }

        // We didn't find the variable.
        else return NULL;
    };

    //! Gets the variable with the given name.
    //! @param name          Name of the variable.
    //! @return The value of the given variable.
    //! @note Specialization function for std::string.
    std::string getVar(const std::string &name);

    //! Removes all variables from this DataStack.
    void removeVars();
    //! Removes the variable with the given name.
    //! @param name          Name of the variable.
    bool removeVar(const std::string &name);

    //! Saves the DataStack as a bencoded file.
    //! @param fileName      Filename of the file where the data is stored in.
    bool saveBencode(const std::string &fileName);
    //! Loads the DataStack from a bencoded file.
    //! @param fileName      Filename of the file where the data is retrieved from.
    bool loadBencode(const std::string &fileName);

    //! Saves the DataStack as a XML file.
    //! @param fileName      Filename of the file where the data is stored in.
    bool saveXML(const std::string &fileName);
    //! Loads the DataStack from a XML file.
    //! @param fileName      Filename of the file where the data is retrieved from.
    bool loadXML(const std::string &fileName);

private:

    // Static members
    static u32 mIDCount;

    // Normal members
    u32 mID;
    std::string mName;

    std::map<std::string, std::string> mVars;
};

#endif
